package task

import (
	"EasyReson/reson"
	log "code.google.com/p/log4go"
	"EasyReson/pool"
	"EasyReson/global"
	"database/sql"
)

/**
	处理成功任务的协程
 */
type successUnit struct {
	taskUnit *UnitTask //任务单元对象
	thread int//需要开启多少个协程处理任务
	workSize int//工作池的数量
	workerPool *pool.Pool//提交任务的工作协程池引用
}
/**
	初始化协程池
 */
func (s *successUnit) initWorkerPool(){

	p := pool.NewPool(s.thread, s.workSize).
		Start().
		EnableWaitForAll(true)
	s.workerPool=p
}
/**
	提交成功的任务到协程池
 */
func (s *successUnit) submitSuccessTask(successResults []*ResonSuccess){

	for index := range successResults {
		/*
			一个技术注释：异步任务必须要先将任务要使用的循环体中的变量副本拷贝出来,因为AddJob是延迟执行，如果在
			AddJob 中使用index变量，会获取到错误的记录，导致程序错误
		 */
		successResult := successResults[index]

		s.workerPool.AddJob(func(){

			reson.ExcuseSuccessReWriteSql(s.taskUnit.task.TaskName,s.taskUnit.task.Db1Src,
				s.taskUnit.db1,successResult.db1Data)
			reson.ExcuseSuccessReWriteSql(s.taskUnit.task.TaskName,s.taskUnit.task.Db2Src,
			s.taskUnit.db2,successResult.db2Data)

		})
	}
	s.workerPool.WaitForAll()
	s.workerPool.StopAll()
}

/**
	处理成功任务的协程
 */
type srcFailUnit struct {
	taskUnit *UnitTask //任务单元对象
	thread int//需要开启多少个协程处理任务
	workSize int//工作池的数量
	workerPool *pool.Pool//提交任务的工作协程池引用
	index int //失败的任务的索引，1 表示是src1勾兑失败。2表示是src2勾兑失败
}
/**
	初始化协程池
 */
func (f *srcFailUnit) initWorkerPool(){
	p := pool.NewPool(f.thread, f.workSize).
		Start().
		EnableWaitForAll(true)
	f.workerPool=p
}

/**
	处理失败的勾兑请求
	勾兑失败的，将任务回写到dbDest
	如果勾兑失败的任务配置了任务回写，则也要回写失败的任务的状态
 */
func (f *srcFailUnit) submitFailTask(blendingFails []*ResonFail){

	for index := range blendingFails{

		blendingFail := blendingFails[index]

		f.workerPool.AddJob(func() {

			var columnMapping map[string]string
			var failTable string
			var src *global.DbSrc
			var dbScr *sql.DB

			column := f.taskUnit.task.DBDest.Cloumn
			table := f.taskUnit.task.DBDest.Table
			dbDest := f.taskUnit.dbDest

			if 1 == f.index {
				columnMapping = f.taskUnit.task.DBDest.Db1Mapping
				failTable = f.taskUnit.task.Db1Src.Table
				src = f.taskUnit.task.Db1Src
				dbScr = f.taskUnit.db1
			}
			if 2 == f.index {
				columnMapping = f.taskUnit.task.DBDest.Db2Mapping
				failTable = f.taskUnit.task.Db2Src.Table
				src = f.taskUnit.task.Db2Src
				dbScr = f.taskUnit.db2
			}
			log.Info("taskId [%s] taskName [%s] resonFail table [%s] data [%s]",
				f.taskUnit.task.TaskId, f.taskUnit.task.TaskName, failTable, blendingFail.dbData)

			reson.InsertFailIntoDbDest(columnMapping, blendingFail.dbData, table, column, dbDest)

			reson.ExcuseFailReWriteSql(f.taskUnit.task.TaskName,src,
				dbScr,blendingFail.dbData)

		})
	}
	f.workerPool.WaitForAll()
	f.workerPool.StopAll()
}

